# Copyright (c) 2009-2010 HIT Microelectronic Center
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Gou Pengfei
#

from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
from BaseCPU import BaseCPU
from FUPool import *
from AtomicEdgeCPU import AtomicEdgeCPU

class DerivEdgeCPU(BaseCPU):
    type = 'DerivEdgeCPU'
    abstract = True

    preExecuteCPU = Param.AtomicEdgeCPU(NULL,"CPU for executing in fetch")

    preExecuteMode = Param.Bool(False, '''Execute block before it is
            actually executed''')

    activity = Param.Unsigned(0, "Initial count")

    fuPool = Param.FUPool(DefaultFUPool(), "Functional Unit pool")

    cachePorts = Param.Unsigned(200, "Cache Ports")
    icache_port = Port("Instruction Port")
    dcache_port = Port("Data Port")
    _mem_ports = BaseCPU._mem_ports + ['icache_port', 'dcache_port']

    mapToFetchDelay = Param.Unsigned(1 ,"Map to fetch delay")
    executeToFetchDelay = Param.Unsigned(1, "Execute to fetch "
                                     "delay")
    commitToFetchDelay = Param.Unsigned(1, "Commit to fetch delay")
    executeToMapDelay = Param.Unsigned(1, "Execute to map delay")
    fetchToMapDelay = Param.Unsigned(1,"Fetch to map delay")

    commitToExecuteDelay = Param.Unsigned(1, "Commit to execute delay")
    commitToMapDelay = Param.Unsigned(1, "Commit to map delay")
    issueToExecuteDelay = Param.Unsigned(1, "Issu to execute delay")
    mapToExecuteDelay = Param.Unsigned(1, "Map to execute delay")

    # This is the size of an inst chunk in TRIPS architecture
    fetchWidth = Param.Unsigned(32, "Fetch width")
    mapWidth = Param.Unsigned(1,"Map width")    # This is in blocks
    issueWidth = Param.Unsigned(16, "Issue width") # This is in insts
    dispatchWidth = Param.Unsigned(160, "Dispatch width") # This is in insts
    wbWidth = Param.Unsigned(16, "Write back width")
    wbDepth = Param.Unsigned(16, "Write back depth")

    executeToCommitDelay = Param.Unsigned(1, "Execute to commit "
               "delay")
    mapToROBDelay = Param.Unsigned(1, "Map to reorder buffer delay")
    commitWidth = Param.Unsigned(1, "Commit width")
    squashWidth = Param.Unsigned(8, "Squash width")

    trapLatency = Param.Tick(1, "Trap latency")

    fetchTrapLatency = Param.Tick(1, "Fetch trap latency")

    LQEntries = Param.Unsigned(256, "Number of load queue entries") 
    SQEntries = Param.Unsigned(256, "Number of store queue entries")
    LFSTSize = Param.Unsigned(1024, "Last fetched store table size")
    SSITSize = Param.Unsigned(1024, "Store set ID table size")

    numIQEntries = Param.Unsigned(1280, "Number of instruction queue entries")
    numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries")

    numPhysIntRegs = Param.Unsigned(128, "Number of physical integer registers")
    numPhysFloatRegs = Param.Unsigned(128, "Number of physical floating point "
                                      "registers")
    backComSize = Param.Unsigned(5, "Time buffer size for backwards communication")
    forwardComSize = Param.Unsigned(5, "Time buffer size for forward communication")

    instShiftAmt = Param.Unsigned(2, "Number of bits to shift instructions by")
    BTBEntries = Param.Unsigned(2048,"Number of BTBEntries")
    #IBTBEntries = Param.Unsigned(256,"Number of IBTBEntries")
    #iExitPredictorEntries = Param.Unsigned(512,"Number of IExitPredictorEntries")
    #iExitLength = Param.Unsigned(3,"Length of iExit")
    CTBEntries = Param.Unsigned(128,"Number of CTBEntries")
    BTPEntries = Param.Unsigned(4096,"Number of BTPEntries")
    blockShiftAmt = Param.Unsigned(7,"Number of bits to shift blocks by")
    offsetLength = Param.Unsigned(13,"Length of offset")
    localPredictorSize = Param.Unsigned(1024, "Size of local predictor")
    localHistoryTableSize = Param.Unsigned(512, "Size of local history table")
    localHistoryBits = Param.Unsigned(10, "Bits for the local history")
    localCtrBits = Param.Unsigned(1, "Bits of local counters")
    globalPredictorSize = Param.Unsigned(4096, "Size of global predictor")
    globalHistoryBits = Param.Unsigned(12, "Bits of global history")
    globalCtrBits = Param.Unsigned(1, "Bits of global counters")
    choiceHistoryBits = Param.Unsigned(12, "Bits of choice history")
    choicePredictorSize = Param.Unsigned(4096, "Size of choice predictor")
    choiceCtrBits = Param.Unsigned(2, "Bits of choice counters")
    RASSize = Param.Unsigned(128,"Size of return address stack")
    lsEntries = Param.Unsigned(128,"Number of LSEntries")

    # Parameters for binary global/local predictors
    binaryLocalPredictorSize = Param.Unsigned(1024, "Size of local predictor")
    binaryLocalHistoryTableSize = Param.Unsigned(512, "Size of local history table")
    binaryLocalHistoryBits = Param.Unsigned(10, "Bits for the local history")
    binaryLocalCtrBits = Param.Unsigned(1, "Bits of local counters")
    binaryGlobalPredictorSize = Param.Unsigned(4096, "Size of global predictor")
    binaryGlobalHistoryBits = Param.Unsigned(12, "Bits of global history")
    binaryGlobalCtrBits = Param.Unsigned(1, "Bits of global counters")
    binaryChoiceHistoryBits = Param.Unsigned(12, "Bits of choice history")
    binaryChoicePredictorSize = Param.Unsigned(4096, "Size of choice predictor")
    binaryChoiceCtrBits = Param.Unsigned(2, "Bits of choice counters")

    msbHistoryBits = Param.Unsigned(24,"Length of history for msb")
    msbWeightTableSize = Param.Unsigned(4096,"Size of msb predictor")
    lsbHistoryBits = Param.Unsigned(36,"Length of history for lsb")
    lsbWeightTableSize = Param.Unsigned(4096,"Size of lsb predictor")
    mbHistoryBits = Param.Unsigned(27,"Length of history for mb")
    mbWeightTableSize = Param.Unsigned(4096,"Size of mb predictor")
    weightBits = Param.Unsigned(8,"Number of bits of a weight")

    pwHistoryBits = Param.Unsigned(10, '''Length of history for
            piecewise predictor''')
    pwLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    pwMsbHistoryBits = Param.Unsigned(24, '''Length of history for
            piecewise predictor''')
    pwMsbLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwMsbPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwMsbTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwMsbLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    pwMbHistoryBits = Param.Unsigned(27, '''Length of history for
            piecewise predictor''')
    pwMbLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwMbPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwMbTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwMbLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    pwLsbHistoryBits = Param.Unsigned(36, '''Length of history for
            piecewise predictor''')
    pwLsbLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwLsbPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwLsbTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwLsbLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    pwtMsbHistoryBits = Param.Unsigned(24, '''Length of history for
            piecewise predictor''')
    pwtMsbLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwtMsbPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwtMsbTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwtMsbLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    pwtLsbHistoryBits = Param.Unsigned(36, '''Length of history for
            piecewise predictor''')
    pwtLsbLocalHistoryBits = Param.Unsigned(0, '''Length of local history for
            piecewise predictor''')
    pwtLsbPathTableSize = Param.Unsigned(32, '''Size of the second
            dimension of piecewise weight table''')
    pwtLsbTableSize = Param.Unsigned(4096, '''Size of the first dimension
            of piecewise weight table''')
    pwtLsbLocalHistoryTableSize = Param.Unsigned(4096, '''Size of the
            local history table''')

    exitPredType = Param.String("Tournament", '''Exit predictor type
            ('Perceptron', 'Tournament','TournamentPerceptron',
            'Perfect', 'TargetOnly', 'PiecewiseExitP')''')

    btypePredType = Param.String("Hysteresis", '''Branch type predictor
            type ('Hysteresis', 'PieceWise', 'PiecewiseSType',
                                 'Perfect')''')

    btbType = Param.String("NewBTB", '''Branch Target Buffer type ('BTB',
            'iBTB', 'NewBTB')''')

    BTBIndexType = Param.String("NoHistory", '''Index type of NewBTB
                                ('NoHistory', 'GlobalHistory', 'PathHistory', 
                               'PredictorHistory')''')

    BTBHistoryLength = Param.Unsigned("8", '''History length for correlative
                                      BTB''')

    BTBTableMode = Param.String('NormalTable', '''Table mode of NewBTB
                                ('NormalTable', 'AliasFree')''')

    iBTBIndexType = Param.String("GlobalHistory", '''Index type of iBTB 
            ('GlobalHistory', 'PathHistory', 'ConPathHistory',
            'HybridHistory')''')

    hystBTypeIndexMode = Param.String("AddressAndExit", '''Index mode
            of hysteresis-based branch type predictor
            ('AddressAndExit', 'Address', 'AddressAndHist',
            'AddressAndPath')''')

    hystBTypeTableMode = Param.String("NormalTable", '''Table mode
            of hysteresis-based branch type predictor
            ('NormalTable', 'AliasFree')''')

    btypeTournamentGlobalIndexMode = Param.String("AddressAndHist", '''Index
            mode of tournament's global branch type predictor
            ('Address', 'AddressAndHist',
            'AddressAndPath')''')

    btypeGlobalIndexMode = Param.String("AddressAndHist", '''Index
            mode of global type predictor
            ('Address', 'AddressAndHist',
            'AddressAndCPath')''')

    btypeTournamentPredictionMode = Param.String("Tournament",
            '''Prediction mode for tournament branch type predictor
            ('Tournament', 'Global', 'Local')''')

    btypeTournamentHysteresisMode = Param.String("Symmetric",
            '''Hysteresis mode for tournament branch type predictor
            ('Symmetric', 'Asymmetric')''')

    btypeGlobalHysteresisMode = Param.String("Symmetric",
            '''Hysteresis mode for global branch type predictor
            ('Symmetric', 'Asymmetric')''')

    btypeLocalHysteresisMode = Param.String("Symmetric",
            '''Hysteresis mode for local branch type predictor
            ('Symmetric', 'Asymmetric')''')

    btypeTableMode = Param.String("Normal",
            '''Table mode for global type predictors ('Normal',
            'AliasFree') ''')

    btypeTageTaggedTableSize = Param.Unsigned(8192, '''Size of the
            tagged tables.''')

    btypeTageDefaultTableSize = Param.Unsigned(131072, '''Size of the
            default table.''')

    btypeTageTaggedCtrBits = Param.Unsigned(3, '''Number of counter
            bits for tagged tables''')

    btypeTageDefaultCtrBits = Param.Unsigned(2, '''Number of counter
            bits for the default table''')

    btypeTageTaggedUsefulCtrBits = Param.Unsigned(2, '''Number of
            useful counter bits of tagged tables''')

    btypeTageTagBits = Param.Unsigned(9, '''Number of tags''')

    btypeTageNumTaggedTables = Param.Unsigned(4, '''Number of tagged
            tables''')

    btypeTageAlpha = Param.Float(1.5, '''Value of alpha for
            generating geometric series''')

    btypeTagel1 = Param.Unsigned(1, '''Minimum length of histories''')

    btypeTageGlobalIndexMode = Param.String("AddressAndHist", '''Index
            mode of TAGE's global branch type predictor
            ('Address', 'AddressAndHist',
            'AddressAndPath', 'AddressAndCPath')''')

    btypeTagePredictionMode = Param.String("GlobalOnly",
            '''Prediction mode for TAGE branch type predictor
            ('GlobalOnly', 'IncludeLocal')''')

    btypeTageTableSizeMode = Param.String("Equal",
            '''Tagged table size mode for TAGE branch type predictor
            ('Equal', 'HistPower')''')

    btypeTwostagePredictionMode = Param.String("PiecewiseAndHyst",
        '''Prediction mode for two-stage type predictors. 
        ('PiecewiseAndHyst')'''
        )

    btypeTourBinaryPredictionMode = Param.String("GlobalLocal",
        '''Prediction mode for binary tournament predictors. 
        ('GlobalLocal', 'CPathLocal')'''
        )

    exitPiecewiseHistMode = Param.String("SingleBitHistory", '''
            History mode of exit piecewise predictor
            ('SingleBitHistory', 'ExitHistory')
            ''')
    typePiecewiseHistMode = Param.String("TypeHistory", '''
            History mode of type piecewise predictor
            ('SingleBitHistory', 'TypeHistory')
            ''')

    memDepMode = Param.String("Normal", '''Memory dependence predictor
            mode ('Normal', 'Perfect')''')

    predicationMode = Param.String("Normal", '''Predication status
            ('Normal', 'Perfect')''')

    exitPiecewiseHistMode = Param.String("SingleBitHistory", '''
            History mode of exit piecewise predictor
            ('SingleBitHistory', 'ExitHistory')
            ''')
    typePiecewiseHistMode = Param.String("SingleBitHistory", '''
            History mode of type piecewise predictor
            ('SingleBitHistory', 'TypeHistory')
            ''')

    memDepMode = Param.String("Normal", '''Memory dependence predictor
            mode ('Normal', 'Perfect')''')

    predicationMode = Param.String("Normal", '''Predication status
            ('Normal', 'Perfect')''')

    bexitTournamentPredictionMode = Param.String("TAGELocal",
            '''Prediction mode for tournament branch type predictor
            ('TAGELocal')''')

#    bexitTournamentHysteresisMode = Param.String("Symmetric",
#            '''Hysteresis mode for tournament branch type predictor
#            ('Symmetric', 'Asymmetric')''')

    bexitGlobalIndexMode = Param.String("AddressAndHist", '''Index
            mode of global exit predictor
            ('Address', 'AddressAndHist',
            'AddressAndCPath')''')

    bexitGlobalHysteresisMode = Param.String("Symmetric",
            '''Hysteresis mode for global branch type predictor
            ('Symmetric', 'Asymmetric')''')

    bexitLocalHysteresisMode = Param.String("Symmetric",
            '''Hysteresis mode for local branch type predictor
            ('Symmetric', 'Asymmetric')''')

    bexitTableMode = Param.String("Normal",
            '''Table mode for exit predictors ('Normal',
            'AliasFree') ''')

    bexitTageTaggedTableSize = Param.Unsigned(4096, '''Size of the
            tagged tables.''')

    bexitTageDefaultTableSize = Param.Unsigned(8192, '''Size of the
            default table.''')

    bexitTageTaggedCtrBits = Param.Unsigned(3, '''Number of counter
            bits for tagged tables''')

    bexitTageDefaultCtrBits = Param.Unsigned(2, '''Number of counter
            bits for the default table''')

    bexitTageTaggedUsefulCtrBits = Param.Unsigned(2, '''Number of
            useful counter bits of tagged tables''')

    bexitTageTagBits = Param.Unsigned(9, '''Number of tags''')

    bexitTageNumTaggedTables = Param.Unsigned(4, '''Number of tagged
            tables''')

    bexitTageAlpha = Param.Float(1.5, '''Value of alpha for
            generating geometric series''')

    bexitTagel1 = Param.Unsigned(1, '''Minimum length of histories''')

    bexitTageGlobalIndexMode = Param.String("AddressAndHist", '''Index
            mode of TAGE's global branch type predictor
            ('Address', 'AddressAndHist',
            'AddressAndPath', 'AddressAndCPath')''')

    bexitTagePredictionMode = Param.String("GlobalOnly",
            '''Prediction mode for TAGE branch type predictor
            ('GlobalOnly', 'IncludeLocal')''')

    bexitTageTableSizeMode = Param.String("HistPower",
            '''Tagged table size mode for TAGE branch type predictor
            ('Equal', 'HistPower')''')

    # SMT related parameters are currently deprecated ...
    smtNumFetchingThreads = Param.Unsigned(1, "SMT Number of Fetching Threads")
    smtFetchPolicy = Param.String('SingleThread', "SMT Fetch policy")
    smtLSQPolicy    = Param.String('Partitioned', "SMT LSQ Sharing Policy")
    smtLSQThreshold = Param.Int(100, "SMT LSQ Threshold Sharing Parameter")
    smtIQPolicy    = Param.String('Partitioned', "SMT IQ Sharing Policy")
    smtIQThreshold = Param.Int(100, "SMT IQ Threshold Sharing Parameter")
    smtROBPolicy   = Param.String('Partitioned', "SMT ROB Sharing Policy")
    smtROBThreshold = Param.Int(100, "SMT ROB Threshold Sharing Parameter")
    smtCommitPolicy = Param.String('RoundRobin', "SMT Commit Policy")

    simPointSim = Param.Bool(True, "Use simpoint or not")
    simPointStartFunctionName = Param.String("", '''Function name of the
            specific start simpoint''')
    simPointEndFunctionName = Param.String("", '''Function name of the specific
            end simpoint''')
    simPointRetNum = Param.Int(-1, "Number of rets to a specific function for a specific simpoint")
    simPointCallNum = Param.Int(-1, "Number of calls to a specific function for a specific simpoint")
    simPointMode = Param.String("Invalid", '''Mode of this simpoint.
    You can choose from 'StartPoint' and 'EndPoint' ''')

    def addPrivateSplitL1Caches(self, ic, dc):
        BaseCPU.addPrivateSplitL1Caches(self, ic, dc)
        self.icache.tgts_per_mshr = 20
        self.dcache.tgts_per_mshr = 20

